package cam.School.DataAccessObjectImpl;

import static cam.School.DataAccessObject.DAOUtil.close;
import static cam.School.DataAccessObject.DAOUtil.prepareStatement;

import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import cam.School.DAOException.DAOException;
import cam.School.DataAccessObject.DAOFactory;
import cam.School.DataAccessObject.ImageDAO;
import cam.School.DataTransfertObject.CallResult;
import cam.School.DataTransfertObject.ImageDTO;

public class ImageDAOImpl implements ImageDAO {
	// Constants
	// ----------------------------------------------------------------------------------

	private static final String QUERY_PARAMS = "id, objectId, location";

	private static final String INSERT_PARAMS = "(objectId, location)";

	private static final String UPDATE_QUERY_PARAMS = "objectId = ?, location = ?";

	private static final String SQL_FIND_BY_ID = "SELECT " + QUERY_PARAMS
			+ " FROM image WHERE  objectId = ?";

	private static final String SQL_INSERT = "INSERT INTO image "
			+ INSERT_PARAMS + " VALUES (?, ?)";

	private static final String SQL_DELETE = "DELETE FROM image WHERE id = ?";

	private static final String SQL_UPDATE = "UPDATE image SET "
			+ UPDATE_QUERY_PARAMS + " WHERE id = ?";
	
	private static final String SQL_UPDATE_IMAGE_BY_USER_ID = "UPDATE Image" 
			+ " SET location = ? WHERE  objectId = ?";

	// Vars
	// ---------------------------------------------------------------------------------------

	private DAOFactory daoFactory;

	// Constructors
	// -------------------------------------------------------------------------------

	/**
	 * Construct an image DAO for the given DAOFactory. Package private so
	 * that it can be constructed inside the DAO package only.
	 * 
	 * @param daoFactory
	 *            The DAOFactory to construct this image DAO for.
	 */
	public ImageDAOImpl(DAOFactory daoFactory) {
		this.daoFactory = daoFactory;
	}

	private ImageDTO find(String sql, Object... values) throws DAOException {
		Connection connection = null;
		PreparedStatement preparedStatement = null;
		ResultSet resultSet = null;
		ImageDTO image = null;

		try {
			connection = daoFactory.getConnection();
			preparedStatement = prepareStatement(connection, sql, false, values);
			resultSet = preparedStatement.executeQuery();
			if (resultSet.next()) {
				image = map(resultSet);
			}
		} catch (SQLException e) {
			throw new DAOException(e);
		} finally {
			close(connection, preparedStatement, resultSet);
		}

		return image;
	}

	private static ImageDTO map(ResultSet resultSet)
			throws SQLException {
		ImageDTO image = new ImageDTO();
		image.setId(resultSet.getLong("id"));
		image.setPictureData(resultSet.getString("pictureData"));
		image.setObjectId(resultSet.getLong("objectId"));
		image.setUploadFrom(resultSet.getString("uploadFrom"));
		return image;
	}

	@Override
	public CallResult upload(long objectId, String filepath)
			throws IllegalArgumentException, DAOException, IOException {
		Object[] values = {
				objectId, 
				filepath
		};
		
		Connection connection = null;
		PreparedStatement preparedStatement = null;

		try {
			connection = daoFactory.getConnection();
			preparedStatement = prepareStatement(connection, SQL_INSERT, false,
					values);
			int affectedRows = preparedStatement.executeUpdate();
			if (affectedRows == 1) {
				return new CallResult(200,"added");
			} else {
				return new CallResult(406,"not saved");
			}
		} catch (SQLException e) {
			return new CallResult(406,e.toString());
		} finally {
			close(connection, preparedStatement);
		}
	}

	@Override
	public void update(ImageDTO image) {
		// TODO Auto-generated method stub

	}

	@Override
	public void delete(long objectIdBelongTo) {
		// TODO Auto-generated method stub

	}

	@Override
	public ImageDTO[] findAll() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public ImageDTO getFileById(long objectIdBelongTo) throws DAOException,
			IOException {
		return find(SQL_FIND_BY_ID, objectIdBelongTo);
	}

	
	public CallResult update(Object[] values, String sql) {
		Connection connection = null;
		PreparedStatement preparedStatement = null;

		try {
			connection = daoFactory.getConnection();
			preparedStatement = prepareStatement(connection, sql, false,
					values);
			int affectedRows = preparedStatement.executeUpdate();
			if (affectedRows == 1) {
				return new CallResult(200,"added");
			} else {
				return new CallResult(406,"not saved");
			}
		} catch (SQLException e) {
			return new CallResult(406,e.toString());
		} finally {
			close(connection, preparedStatement);
		}		
	}
	
	@Override
	public CallResult updateEmployeeImage(long objectId, String filepath)
			throws IllegalArgumentException, DAOException, IOException {
		Object[] values = {
				objectId, 
				filepath
		};
		return update(values, SQL_UPDATE_IMAGE_BY_USER_ID);		
	}

}